#include "AudioBuffer.h"
#include "BrowseForFolderDialog.h"
#include "Composition.h"
#include "MixdownDialog.h"
#include "Track.h"
#include "WaveFile.h"

using namespace std;

MixdownDialog::MixdownDialog(HINSTANCE hInstance, const Composition *composition) throw(): Dialog(hInstance, TEXT("Create mixdown"), CS_OKCANCEL), m_composition(composition) {
    m_hFreqLabel = CreateWindow(TEXT("STATIC"), TEXT("Sample rate:"), WS_CHILD | WS_VISIBLE | SS_LEFT, widthToPixels(4), heightToPixels(4), widthToPixels(width() - 8), heightToPixels(8), hWnd(), 0, hInstance, 0);
    m_hFreq = CreateWindow(TEXT("COMBOBOX"), 0, WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | CBS_HASSTRINGS, widthToPixels(4), heightToPixels(16), widthToPixels(width() - 8), heightToPixels(64), hWnd(), 0, hInstance, 0);
    SendMessage(m_hFreq, CB_ADDSTRING, 0, LPARAM(TEXT("11025Hz")));
    SendMessage(m_hFreq, CB_ADDSTRING, 0, LPARAM(TEXT("22050Hz")));
    SendMessage(m_hFreq, CB_ADDSTRING, 0, LPARAM(TEXT("44100Hz")));
    SendMessage(m_hFreq, CB_SETCURSEL, 0, 0);

    m_hChannelsLabel = CreateWindow(TEXT("STATIC"), TEXT("Channels:"), WS_CHILD | WS_VISIBLE | SS_LEFT, widthToPixels(4), heightToPixels(36), widthToPixels(width() - 8), heightToPixels(8), hWnd(), 0, hInstance, 0);
    m_hChannels = CreateWindow(TEXT("COMBOBOX"), 0, WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | CBS_HASSTRINGS, widthToPixels(4), heightToPixels(48), widthToPixels(width() - 8), heightToPixels(64), hWnd(), 0, hInstance, 0);
    SendMessage(m_hChannels, CB_ADDSTRING, 0, LPARAM(TEXT("Mono")));
    SendMessage(m_hChannels, CB_ADDSTRING, 0, LPARAM(TEXT("Stereo")));
    SendMessage(m_hChannels, CB_SETCURSEL, 0, 0);

    m_hBpsLabel = CreateWindow(TEXT("STATIC"), TEXT("Bits per sample:"), WS_CHILD | WS_VISIBLE | SS_LEFT, widthToPixels(4), heightToPixels(68), widthToPixels(width() - 8), heightToPixels(8), hWnd(), 0, hInstance, 0);
    m_hBps = CreateWindow(TEXT("COMBOBOX"), 0, WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | CBS_HASSTRINGS, widthToPixels(4), heightToPixels(80), widthToPixels(width() - 8), heightToPixels(64), hWnd(), 0, hInstance, 0);
    SendMessage(m_hBps, CB_ADDSTRING, 0, LPARAM(TEXT("8 bits")));
    SendMessage(m_hBps, CB_ADDSTRING, 0, LPARAM(TEXT("16 bits")));
    SendMessage(m_hBps, CB_SETCURSEL, 0, 0);
}

MixdownDialog::~MixdownDialog() {
    DestroyWindow(m_hBpsLabel);
    DestroyWindow(m_hBps);
    DestroyWindow(m_hChannels);
    DestroyWindow(m_hChannelsLabel);
    DestroyWindow(m_hFreq);
    DestroyWindow(m_hFreqLabel);
}

bool MixdownDialog::close(CloseCommand cc) throw() {
    if(cc == CC_OK) {
        BrowseForFolderDialog browse(hInstance(), TEXT("Mixdown filename"));
        if(browse.open() == CC_OK) {
            SetCursor(LoadCursor(0, IDC_WAIT));

            TCHAR filename[MAX_PATH];
            _tcscpy(filename, browse.selectedPath());
            _tcscat(filename, TEXT("\\"));
            _tcscat(filename, browse.selectedFile());
            _tcscat(filename, TEXT(".wav"));

            unsigned int freq = 11025;
            switch(SendMessage(m_hFreq, CB_GETCURSEL, 0, 0)) {
                case 0:
                    freq = 11025;
                    break;
                case 1:
                    freq = 22050;
                    break;
                case 2:
                    freq = 44100;
                    break;
                default:
                    ASSERT(!"Unsupported audio format!");
                    break;
            }
            unsigned int numChannels = 1;
            switch(SendMessage(m_hChannels, CB_GETCURSEL, 0, 0)) {
                case 0:
                    numChannels = 1;
                    break;
                case 1:
                    numChannels = 2;
                    break;
                default:
                    ASSERT(!"Unsupported audio format!");
                    break;
            }
            unsigned int bytesPerSample = 1;
            switch(SendMessage(m_hBps, CB_GETCURSEL, 0, 0)) {
                case 0:
                    bytesPerSample = 1;
                    break;
                case 1:
                    bytesPerSample = 2;
                    break;
                default:
                    ASSERT(!"Unsupported audio format!");
                    break;
            }
            AudioBuffer *buffer = new AudioBuffer(8192, numChannels, freq, bytesPerSample);
            WaveFile *file = WaveFile::create(filename, freq, numChannels, bytesPerSample);
            for(MusicTime time = m_composition->startTime(); time < m_composition->endTime(); time += MusicTime(8192, freq)) {
                buffer->clear();
                for(list<Track *>::const_iterator iter = m_composition->tracks().begin(); iter != m_composition->tracks().end(); iter++) {
                    (*iter)->superPositionSegments(buffer, time);
                }
                file->write(buffer);
            }
            file->finalize();
            delete(file);
            delete(buffer);

            SetCursor(0);
        }
        else {
            return(false);
        }
    }

    return(true);
}

void MixdownDialog::controlNotification(HWND hWnd, WPARAM notification) throw() {
}

void MixdownDialog::menuNotification(unsigned int itemId) throw() {
}
